/**
 * Created by lj on 2018/1/9.
 */

load("js/luaclient.js")

var cardIndex = 1;
var PSessionId;
var ReqSafeFields;
var chbFormReqSafeFields;
var card;
var data = new CreditCardAllData();
var dataList = new ArrayList();
var passwords = "!\"#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
var cardList = new ArrayList();
var cardMap = new LinkedHashMap();
var cardIDMap = new LinkedHashMap();
var types = new LinkedHashMap();
var chrs = new HashMap();

function init() {
    var cs = new Array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
    for (var i = 0; i < 11; i++) {
        chrs.put(cs[i], i);
    }
    types.put("工资", "SALARY");
    types.put("奖金", "BONUS");
    types.put("利息", "ACCRUAL");
    types.put("存现", "DEPOSIT");
    types.put("转账", "TRANSFER");
    types.put("普通汇兑", "TRANSFER");
    types.put("借货", "LOANS");
    types.put("冲账", "REVERSE");
    types.put("退款", "REFUND");
    types.put("结息转入", "EARNINGS");
    types.put("收益", "EARNINGS");
    types.put("报销", "CLAIM");
    types.put("其它收入", "OTHERREVENUE");
    types.put("燃油补贴", "OTHERREVENUE");
    types.put("取现", "WITHDRAW");
    types.put("支取", "WITHDRAW");
    types.put("手续费", "HANDLINGFEE");
    types.put("转账", "TRANSFER");
    types.put("网银入账", "TRANSFER");
    types.put("网银转入", "TRANSFER");
    types.put("还贷", "REPAYMENT");
    types.put("理财", "FINANCE");
    types.put("活转定", "FINANCE");
    types.put("存款户现金存款", "FINANCE");
    types.put("翼支付", "CONSUMPTION");
    types.put("消费", "CONSUMPTION");
    types.put("消费", "CONSUMPTION");
    types.put("出金", "CONSUMPTION");
    types.put("快捷支付", "CONSUMPTION");
    types.put("房租", "RENT");
    types.put("公积金", "FUND");
    types.put("社保", "SOCIALSECURITY");
    types.put("通讯费", "COMMUNICATIONFEE");
    types.put("生活费", "LIVINGEXPENSE");
    types.put("其它费用", "OTHERFEE");
    types.put("其它支出", "OTHEREXPENSE");
}

var v4_comm_java_funcs = {

    openHomePage : function(){
        var loginUrl = "https://pbank.95559.com.cn/personbank/logon.jsp"; // 网银入口
        var html = get(loginUrl);
        context.put("html", html)
        storeDataToFile(context, html, "loginIframe.html")
    },
    checkControlAvailable: function () {
        return true
    },
    checkTargetWebsiteAvailable: function(){
        var isCorrectFunc = function () {
            return true
        }
        var getErrorMsgFunc = function () {
            return ""
        }
        return assertTrueOrThrowException("", isCorrectFunc, getErrorMsgFunc)

    },
    //检查代理是否可用
    checkProxyAvailable: function () {
        logger.info("COMM taskKey={}检查当前代理是否可用{}", context.get(LUA_TASK_KEY), context.get(LUA_TASK_PROXY));
        var html = context.get("html")
        var checkProxyRight = function (html) {
            return !(html.contains("代理服务器没有响应") || html.contains("无法显示此页"))
        }
        var getProxyErrorMsg = function (html) {
            return "代理ip异常"
        }
        return assertTrueOrThrowException(html, checkProxyRight, getProxyErrorMsg)
    },
    login: function () {
        inputBaseComm();
        queryImgPath();
        inputImgComm();
        inputSmsComm();
    },
    //抓取过程
    crawl: function () {
        crawlComm();
    },
    exitLogin: function () {
    },
    //如果验证码错误，重新刷新页面
    needRefreshHomePageOrNot : function() {
        return false;
    },
    needResetEnvironment:function(){
        return equals(context.get("currentErrorCode"),BALO_99602_50);
    }

}
//输入账户和密码
function inputBaseComm() {

    var inputResult = {};
    var isCorrectFunc = function (inputResult) {
        var username = getLoginParams(context)[0];
        if (StringUtils.isBlank(username)) {
            logger.info("COMM taskKey=【{}】,账号输入有误，acount:【{}】", context.get(LUA_TASK_KEY), username);
            throw new BankException(BankConstants.BALO_22001_10, "用户名输入有误");
        }
        var password = context.get(LUA_TASK_TOKEN);
        if (StringUtils.isBlank(password) || password.length < 6) {
            logger.info("COMM taskKey=【{}】,密码输入有误, 密码最少6位", context.get(LUA_TASK_KEY));
            throw new BankException(BankConstants.BALO_22001_10, "密码输入有误, 密码最少6位");
        }
        if (password.length > 20) {
            logger.info("COMM taskKey=【{}】,密码输入有误, 密码最长20位", context.get(LUA_TASK_KEY));
            throw new BankException(BankConstants.BALO_22001_10, "密码输入有误, 密码最长20位");
        }

        if (!checkPassword(password)) {
            logger.info("COMM taskKey=【{}】,密码输入有误, 密码中包含非法字符", context.get(LUA_TASK_KEY));
            throw new BankException(BankConstants.BALO_22001_10, "密码输入有误, 密码中包含非法字符");
        }
        logger.info("COMM taskKey=【{}】,账户=【{}】，密码=【{}】", context.get(LUA_TASK_KEY), username, password);

        //输入账号
        set_frame_input_text_by_id("alias", username, 'bannerLogin')
        //输入密码
        var flag = luaFuncs.inputPwd(password);
        logger.info("COMM taskKey=【{}】,输入密码之后的返回值flag : {}",context.get(LUA_TASK_KEY), flag);
        if (StringUtils.equals(flag, "0") || flag.length != password.length) {
            logger.info("COMM taskKey=【{}】, 控件输入密码异常！输入长度:{} 与密码长度:{} 不一致。",
                context.get(LUA_TASK_KEY), flag.length, password.length);
            inputResult.errorMsg = "密码因控件输入错误";
            return false;
        } else if (flag.equals("EMPTY")) {
            inputResult.errorMsg = "插件未安装";
            return false;
        }
        return true;
    }
    var getErrorMsg = function (inputResult) {
        return inputResult.errorMsg;
    }
    return assertTrueOrThrowException(inputResult, isCorrectFunc, getErrorMsg)
}
//检查密码
function checkPassword(password) {
    if (StringUtils.isBlank(password)) {
        logger.info("密码是空白字符");
        return false;
    }
    for (var i = 0; i < password.length; i++) {
        var c = password.charAt(i);
        if (passwords.indexOf(c) == -1) {
            logger.info("密码不合法,不包含 [{}]", c);
            return false;
        }
    }
    return true;
}
//获取图片验证码
function queryImgPath(){
    var imgPathResult = {}
    var checkImgPathFunc = function(imgPathResult) {
        var code =""
        var path  = luaFuncs.getCaptcha();
        logger.info("交通银行taskKey = 【{}】,图片验证码路径:【{}】",context.get(LUA_TASK_KEY), path);
        if ("no".equals(path)) {
            logger.info("交通银行taskKey = 【{}】, 此次登录不需要图片验证码", context.get(LUA_TASK_KEY));
            return true;
        }else{
            var times = 1
            context.put(TASK_IMG_PATH, path);
            context.put(TASK_IMG_REGEX,"[0-9a-zA-Z]{4,5}");
            luaFuncs.commShow();
            code = waitImgCodeBySecondsByJs(context,60,true,3)

            while((code == null || code.length < 5)&&times<=3){
                click_frame_by_id("jt_CaptchaImg","bannerLogin")
                Thread.sleep(500); // 等待加载新的验证码
                path = luaFuncs.getCaptcha();
                context.put(TASK_IMG_PATH, path);
                code = waitImgCodeBySecondsByJs(context,60,true,3)
                times++;
            }
            if(code == null || code.length < 5){
                imgPathResult.error = "图片验证码错误"
                return false;
            }
            context.put("needImgCode",true)
            context.put("imgCode",code)
            logger.info("交通银行 taskKey = 【{}】，获取的图片验证码:【{}】",context.get(LUA_TASK_KEY),code);
            return true;
        }
    }
    var getImgPathErrorMsg = function (imgPathResult) {
        return imgPathResult.error
    }
    assertTrueOrThrowException(imgPathResult, checkImgPathFunc, getImgPathErrorMsg)
}
//输入图片验证码
function inputImgComm() {
    if(context.get("needImgCode")){
        var imgResult = {}
        var checkImgFunc = function (imgResult) {
            var codeMsg = luaFuncs.inputCaptcha(context.get("imgCode"));
            logger.info("交通银行taskKey = 【{}】，输入验证码返回信息:【{}】",context.get(LUA_TASK_KEY),codeMsg);
            if ("ok".equals(codeMsg)) {
                return true;
            } else if("no".equals(codeMsg)) {
                logger.error("交通银行taskKey = 【{}】，验证码输入错误", context.get(LUA_TASK_KEY));
                imgResult.error = "图片验证码错误";
                return false;
            }else if("no_error".equals(codeMsg)){
                imgResult.error = codeMsg;
                return false;
            }
        }
        var getImgErrorMsg = function (imgResult) {
            return imgResult.error
        }
        return assertTrueOrThrowException(imgResult,checkImgFunc,getImgErrorMsg)
    }
}
//输入短信验证码
function inputSmsComm() {
    var loginResult = {};
    var checkLoginFunf = function (loginResult) {
        luaFuncs.saveHtmlAndImageFunc("afterLogin");
        var currentHtml = get_html();
        var doc = Jsoup.parse(currentHtml);
        var errorElement =  doc.select(".lanse-12-b");
        if(!(errorElement.isEmpty())){
            logger.info("交通银行taskKey = {}，登录未成功，获取到的登录错误信息：{}", context.get(LUA_TASK_KEY),errorElement);
            loginResult.errorMsg = errorElement.get(0).text();
            return false;
        }
        logger.info("交通银行taskKey = {}，开始验证登录，准备验证短信验证码.", context.get(LUA_TASK_KEY));
        // 判断，并发送短信验证码
        var msg = dologinSendSms();
        logger.info("交通银行taskKey = {}，验证登录、发送短信返回值 : {}", context.get(LUA_TASK_KEY), msg);
        if ("ok".equals(msg)) { // 不需要短信，直接登录
            logger.info("不需要短信,直接登录");
            return true;
        } else if ("no".equals(msg)) { // 出错
            logger.info("没有检测出ID,再校验异常是否登录成果");
            var r = is_exist_by_id("frameMain");
            logger.info("登录结果 : {} ", r);
            if (!r) {
                loginResult.errorMsg = "短信验证码错误";
            }
            return r;
        } else if ("sms".equals(msg)) {
            logger.info("交通银行，等待输入短信验证码.");
            var verifyMessage = waitSmsCodeBySeconds(context,180);
            logger.info("交通银行，短信验证码 : " + verifyMessage);
            var flag = luaFuncs.inputMobileCode(verifyMessage);
            logger.info("交通银行，短信验证返回值 : {}", flag);
            if (StringUtils.equals("yes", flag)) {
                logger.info("交通银行taskKey = {}，短信验证提交成功,正在等待页面跳转...", context.get(LUA_TASK_KEY));
                var confMsg = luaFuncs.setConfirm();
                var time = 2;
                while (time-- > 0) {
                    logger.info("交通银行，短信验证返回值 : {}, time:{}", confMsg, time);
                    if (confMsg.contains("代理服务器没有响应")) {
                        logger.info("交通银行taskKey = {} 代理IP异常:{}", context.get(LUA_TASK_KEY), context.get(LUA_TASK_PROXY));
                        throw new BankException(BankConstants.BALO_99601_10, "306 代理IP异常 : " + context.get(LUA_TASK_PROXY));
                    } else if (confMsg.contains("tranArea")) {
                        var vMsg = confMsg.contains("页面(html)加载完成") ? confMsg : "";
                        logger.info("交通银行taskKey = {} 页面跳转信息 : {}", context.get(LUA_TASK_KEY), vMsg);
                        return true;
                    } else {
                        logger.info("交通银行taskKey = {} 判断页面加载，剩余次数:{}", context.get(LUA_TASK_KEY), time);
                        confMsg = luaFuncs.checkIsOk();
                    }
                }
                if (confMsg.contains("tranArea")) {
                    var vMsg = confMsg.contains("页面(html)加载完成") ? confMsg : "";
                    logger.info("交通银行taskKey = {} 页面跳转信息 : {}", context.get(LUA_TASK_KEY), vMsg);
                    return true;
                } else {
                    logger.info("交通银行taskKey = {} 代理IP异常:{}", context.get(LUA_TASK_KEY), context.get(LUA_TASK_PROXY));
                    throw new BankException(BankConstants.BALO_99601_10, "306 代理IP异常 : " + context.get(LUA_TASK_PROXY));
                }
            } else if ("ok".equals(flag)) {
                return true;
            } else if ("no".equals(flag)) { // 出错
                throw new BankException(BankConstants.BALO_23001_10, flag);
            } else {
                logger.info("交通银行 登录失败 " + flag);
                if (flag.contains("动态密码有误") || flag.contains("短信附加码输入有误")) {
                    throw new BankException(BankConstants.BALO_99602_40, flag);
                } else if(flag.contains("PEBS0004SY0142:您已通过其它设备登录，如非您本人操作")) {
                    throw new BankException(BankConstants.BACR_99602_10, flag);
                }else {
                    throw new BankException(BankConstants.BALO_23001_10, flag);
                }
            }
        } else {
            if (msg.contains("未注册或登录密码输入错误")) {
                loginResult.errorMsg = "尚未注册或登录密码输入错误";
            } else if (msg.contains("密码连续错误次数")) {
                loginResult.errorMsg = msg
            } else if (msg.contains("系统错误")) {
                loginResult.errorMsg = "系统错误，请稍后再试";
            } else if (msg.contains("还未添加银行卡")) {
                loginResult.errorMsg = "还未添加银行卡，请前往官网进行添加";
            } else if (msg.contains("需开启身份证登录")) {
                // 如需开启身份证登录，请使用昵称或卡号登录后，进入“网银设置-个人中心-网银资料-用户名登录”修改开启，即可使用。
                loginResult.errorMsg = "您尚未开启身份证登录或登录密码输入错误";
            } else {
                loginResult.errorMsg = msg
            }
            return false;
        }
    }
    var getLoginErrorMsg = function (loginResult) {
        return loginResult.errorMsg;
    }
    return assertTrueOrThrowException(loginResult, checkLoginFunf, getLoginErrorMsg)


}
// 点击登录 等待跳转短信验证页面 并发送验证码
function dologinSendSms() {
    var max = 30;
    var isSms = false;
    var isError = false;
    var isOK = false;
    var alert = "";
    luaFuncs.saveHtmlAndImageFunc("waitSms");
    for (var i = 0; i < max && !isSms && !isError && !isOK; i++) {
        isSms = is_exist_by_id("authSMSSendBtn");
        isError = is_exist_by_id("backBtn");
        isOK = is_exist_by_id("frameMain");
        var btnConf1 = is_exist_by_id("btnConf1");
        if (btnConf1 && max == 30) {
            luaFuncs.saveHtmlAndImageFunc("waitSms1");
            click_by_id("btnConf1");
            max = 60;
            logger.info("发现确定按钮,多等一会...");
        }
        logger.info("sms : {} ,error : {} ,ok : {} ,button : {}", isSms, isError, isOK, btnConf1);
        try {
            Thread.sleep(1000);
        } catch (e) {

            statCaughtExceptionByJS(context, e);
            logger.error(e.message, e);
        }
        alert = get_alert_msg();
        if (StringUtils.isNotBlank(alert)) {
            logger.info("弹出对话框 : {} ", alert);
            return alert;
        }
    }
    luaFuncs.saveHtmlAndImageFunc("waitSms2");
    var btnConf1Flag = is_exist_by_id("btnConf1");
    if (btnConf1Flag) {
        luaFuncs.saveHtmlAndImageFunc("waitSms3");
        click_by_id("btnConf1");
        logger.info("二次发现确定按钮");
        try {
            Thread.sleep(1000);
        } catch (e) {
            statCaughtExceptionByJS(context, e);
            logger.error(e.message, e);
        }
    }

    if (isSms) {
        click_by_id("authSMSSendBtn");
        return "sms";
    }
    if (isOK) {
        return "ok";
    }
    var html = get_html();
    var doc = Jsoup.parse(html);
    if (isError) {
        var errorMsg = doc.select(".lanse-12-b").text();
        return errorMsg;
    }
    var msg = doc.select("#certMask p").text();
    if (StringUtils.isNotBlank(msg)) {
        return msg;
    }
    return "no";
}

function crawlComm() {
    logger.info("交通银行taskKey:{},开始抓取借记卡数据...", context.get(LUA_TASK_KEY));
    dealCardList();
    var entrySet= cardMap.keySet();
    for each(var cardNo  in entrySet) {
        card = cardNo;
        if (cardMap.get(cardNo).equals(CardType.DEBITCARD.toString())) {
            crawlDebit();//借记卡抓取
        }
        cardIndex++;
    }
    context.put("all_data", dataList);
}
//获取卡列表
function dealCardList() {
    var index = get_html();
    PSessionId = getGroup1("PSessionId=(.*?)&", index);
    var cookie = get_cookie();
    var header = new LinkedHashMap();
    header.put("cookie", cookie);
    var safeUrl = "https://pbank.95559.com.cn/personbank/system/syCardList.ajax?PSessionId=" + PSessionId
        + "&x-channel=0&tab=0&menuCode=P001001&random=" + Math.random() + "&_=" + System.currentTimeMillis();
    var safeJSON=RequestUtil.get(safeUrl, null, header);
    storeDataToFile(context,safeJSON, "safeJSON.txt");
    context.put("safeJSON",safeJSON);

    ReqSafeFields = getGroup1("safeValue\":\\s{0,}\"(.*?)\"", safeJSON);
    var url = "https://pbank.95559.com.cn/personbank/account/acQuery.do?PSessionId=" + PSessionId + "&x-channel=0&tab=0&menuCode=P001001";
    var cardListContent = RequestUtil.get(url,null,header);
    context.put("cardListContent",cardListContent);
    analysisCardList();  //解析卡列表

    var retryTimes = 0;
    while(cardMap.size() == 0&&retryTimes<3){
        logger.info("交通银行taskKey:{}，休眠5s后重试获取借记卡列表...",context.get(LUA_TASK_KEY));
        Thread.sleep(5000);
        cardListContent=RequestUtil.get(url,null,header);
        context.put("cardListContent",cardListContent);
        analysisCardList();
        retryTimes++;
    }
    storeDataToFile(context,cardListContent, "cardList.html");
    if (cardMap.size() == 0) {
        logger.info("交通银行taskKey:{}，未获取卡列表...", context.get(LUA_TASK_KEY));
        throw new BankException(BankConstants.BALO_20304_30, "未获取卡列表");
    }
}
//解析卡列表
function analysisCardList() {
    try {
        var doc = Jsoup.parse(context.get("cardListContent"));
        var trs = doc.select("body table > tbody > tr");
        chbFormReqSafeFields = doc.select("input[name='ReqSafeFields']").attr("value");
        if (trs.size() > 0) {
            for each(var element in trs) {
                var tds = element.select("td");
                if (tds.size() == 8) {
                    var cardNo = tds.get(0).text();// 卡号
                    if (tds.text().contains("借记卡")) {
                        cardMap.put(cardNo, "DEBITCARD");
                        var as = element.select("a");
                        for each(var element2 in as) {
                            if (element2.text().equals("明细")) {
                                var onlick = element2.attr("onclick");
                                cardIDMap.put(cardNo, getGroup1("showDetail2\\('(.*?)',", onlick));
                                break;
                            }
                        }
                    } else {
                        cardMap.put(cardNo, "CREDITCARD");
                    }
                } else {
                    if (tds.size() > 0) {
                        logger.info(element.text());
                    }
                }
            }
        }
        logger.info("卡信息情况 {} ", cardMap);
    } catch (e) {
        logger.info("交通银行taskKey:{}，获取卡列表异常:{}", context.get(LUA_TASK_KEY),e);
    }
}
//抓取基本信息
function queryBasicInfo(){
    logger.info("交通银行信用卡 taskKey:{}, 开始抓取基本信息...",context.get(LUA_TASK_KEY));
    var basicInfo = luaFuncs.getCardInfo(card);
    storeDataToFile(context,basicInfo, cardIndex + "_basicInfo.html");
    context.put("basicInfo",basicInfo);
}
//获取金额
function getAmount( jiner) {
    if (jiner == null || jiner.replaceAll("[^\\d]", "").equals("")) {
        return null;
    }

    if (jiner.contains("+")) {
        var jiners = jiner.split("\\+");
        var d = 0;
        for each(var string in jiners) {
            d = d + getAmount(string).doubleValue();
        }
        return getAmount("" + d);
    }
    jiner = jiner.replaceAll("￥", "").trim();
    jiner = jiner.replaceAll("¥", "").trim();
    jiner = jiner.replaceAll("\\s*", "").trim();
    jiner = jiner.trim().equals("") ? "0" : jiner;
    var a = 0;
    jiner = jiner.trim();
    if (jiner.matches(".*?\\.\\d{1,}\u5143")) {
        var newjiner = jiner.replaceAll("(.*?\\.\\d{1,})\u5143", "$1");
        newjiner = newjiner.replaceAll("[^\\d\\.]", "");
        a = Double.parseDouble(newjiner);
    } else if (jiner.matches("\\d{1,}\\.\\d{1,}")) {
        a = Double.parseDouble(jiner);
    } else if (jiner.matches("\\d{1,}")) {
        a = Double.parseDouble(jiner);
    } else if (jiner.matches("(\\+|-)\\d{1,}\\.\\d{1,}")) {
        a = Double.parseDouble(jiner);
    } else if (jiner.matches("(\\+|-)\\d{1,}")) {
        a = Double.parseDouble(jiner);
    } else {
        var newjiner = jiner.replaceAll("[^\\d\\.\\+\\-]", "");
        try {
            a = Double.parseDouble(newjiner);
        } catch ( e) {
            statCaughtExceptionByJS(context, e);
            logger.error(e.message + "------" + jiner, e);
        }
    }
    var b = new BigDecimal(a);
    return b.setScale(2, BigDecimal.ROUND_HALF_UP);
}

function crawlDebit() {
    data = new CreditCardAllData();
    data.setCashBalance(null);
    data.setCashLimit(null);
    data.setCreditLimit(null);
    dataList.add(data);
    queryDebitInfo();
    analysisDebitInfo();
    queryDebitDetails();
    analysisDebitDetails();
    queryDebitDeposits();
    analysisDebitDeposits();
    logger.info("交通银行借记卡 taskKey:{},卡号为{}的数据抓取解析完成...", context.get(LUA_TASK_KEY),card);
}
//抓取借记卡基本信息
function queryDebitInfo() {
    logger.info("交通银行借记卡 taskKey:{}，开始抓取基本信息...",context.get(LUA_TASK_KEY));
    var cardURl = "https://pbank.95559.com.cn/personbank/customer/csCyberBankData.do?PSessionId=" + PSessionId
        + "&x-channel=0&tab=2&menuCode=P062002&random=" + Math.random() + "&ReqSafeFields=" + ReqSafeFields;
    var header = new LinkedHashMap();
    header.put("cookie", get_cookie());
    var content1 = RequestUtil.get(cardURl, null, header);
    storeDataToFile(context,content1, cardIndex +"_debitCard.html");
    context.put(cardIndex +"_debitCard",content1);
}
//解析借记卡基本信息
function analysisDebitInfo(){
    try {
        logger.info("交通银行借记卡 taskKey:{}，开始解析基本信息...",context.get(LUA_TASK_KEY));
        var doc = Jsoup.parse(context.get("cardListContent"));
        var trs = doc.select("body table > tbody > tr");
        if (trs.size() > 0) {
            var tds = trs.get(0).select("td");
            if (tds.size() == 8) {
                var cardNo = tds.get(0).text().replaceAll("\\s", "");// 卡号
                //if (cardNo.equals(card.replaceAll("\\s", ""))) {
                var bank_name = "交通银行";// 银行名称
                data.setCardId(UUID.randomUUID().toString());
                data.setBankName(bank_name);
                data.setFullCardNum(cardNo); // 完整卡号
                data.setCardNum(cardNo.substring(cardNo.length - 4, cardNo.length)); // 卡号后四位
                var name = tds.get(1).text(); // 姓名
                data.setNameOnCard(name);
                var card_type = tds.get(3).text();// 银行卡类型
                data.setCardType(card_type);
                var balance = removeIllegal(tds.get(5).text());// 余额
                if (balance !== null) {
                    data.setBalance(new BigDecimal(balance));
                }
                //var _balance = removeIllegal(tds.get(6).text());// 可用余额
                //}
            }
        }

        doc = Jsoup.parse(context.get(cardIndex +"_debitCard"));
        trs = doc.select("table.card-table > tbody > tr");
        for (var i = 0; i < trs.size(); i++) {
            var tr = trs.get(i);
            var th = tr.select("th");
            if (th.size() == 1 && th.text().contains("卡号")) {
                var cardNo = tr.select("td span:eq(0)").text().replaceAll("\\s", "");
                if (cardNo.equals(data.getFullCardNum()) && (i + 1) <= trs.size()) {
                    var tds = trs.get(i + 1).select("table.block > tbody > tr > td");
                    if (tds.size() == 4) {
                        // 开户银行
                        var openDate = tds.get(0).text().trim();
                        data.setOpenTime(yyyy_MM_dd_PARSER.parse(openDate));
                        // 开户银行
                        var openBank = tds.get(1).text().trim();
                        data.setOpenBank(openBank);
                        break;
                    }
                }
            }
        }
    } catch (e) {
        logger.info("交通银行taskKey = {}, 解析借记卡基本信息出错：{}", context.get(LUA_TASK_KEY),e);
    }
}
//抓取借记卡账户明细
function queryDebitDetails() {
    try {
        logger.info("交通银行借记卡 taskKey:{}，开始抓取账户明细...",context.get(LUA_TASK_KEY));
        var months = getNowAnd36Month();
        var c = Calendar.getInstance();
        c.add(Calendar.YEAR, -2);
        c.add(Calendar.DATE, 1);
        var startDate = DateUtil.format(c.getTime(), "yyyyMMdd");
        var endDate = getDateStr(months.get(0), "yyyy-MM-dd", "yyyyMMdd");
        var postdata = new LinkedHashMap();//存放参数信息
        postdata.put("PSessionId", PSessionId);
        postdata.put("x-channel", "0");
        postdata.put("menuCode", "P002000");
        postdata.put("step", "batchDownLoad");
        postdata.put("cardNo", cardIDMap.get(card));
        postdata.put("selectCardNo", card.replaceAll(" ", ""));
        postdata.put("startDate", startDate);
        postdata.put("endDate", endDate);
        postdata.put("acoAcRecord", "");
        postdata.put("queryType", "");
        postdata.put("serialNo", "");
        postdata.put("page", "1");
        var url = "https://pbank.95559.com.cn/personbank/account/acTranRecordQuery.stream";
        var cookie = get_cookie();
        var header = new LinkedHashMap();
        header.put("cookie", cookie);
        var path = getCopyPath(context.get(LUA_TASK_KEY));
        var file = path+cardIndex+"_details.xls";
        var detailsFile = RequestUtil.postAsFile(file, url, postdata, header);
        logger.info("交通银行借记卡 taskKey:{}，账单1下载路径 : {}",context.get(LUA_TASK_KEY),detailsFile);
        //storeDataToFile(context, detailsFile, "detailsFile.xls");
        context.put("detailsFilePath",detailsFile);

        c.add(Calendar.DATE, -1);
        endDate = DateUtil.format(c.getTime(), "yyyyMMdd");
        c.add(Calendar.YEAR, -1);
        c.add(Calendar.DATE, +1);
        startDate = DateUtil.format(c.getTime(), "yyyyMMdd");
        postdata.put("startDate", startDate);
        postdata.put("endDate", endDate);
        var file1 = path+cardIndex+"_details1.xls";
        var detailsFile1 = RequestUtil.postAsFile(file1, url, postdata, header);
        //fileList.add(file1);
        logger.info("交通银行借记卡 taskKey:{}，账单2下载路径 : {}",context.get(LUA_TASK_KEY),detailsFile1);
        //storeDataToFile(context, detailsFile1, "detailsFile1.xls");
        context.put("detailsFile1Path",detailsFile1);
    } catch ( e) {
        logger.info("交通银行借记卡 taskKey:{}，获取账单出错 : {}",context.get(LUA_TASK_KEY),e);
    }
}
//根据taskKey获取复制文件的路径
function getCopyPath(taskKey){
    var year = taskKey.substring(0, 2);
    var month = taskKey.substring(2, 4);
    var day = taskKey.substring(4, 6);
    return "d:\\htmlStorage\\BANK\\"+year+"\\"+month+"\\"+day+"\\"+taskKey+"\\";
}
//解析Excel来获取借记卡账户明细
function analysisDebitDetails() {
    var list = new ArrayList();
    var reader = getReader(new File(context.get("detailsFilePath")));
    var list1 = reader.read();
    list.addAll(list1);
    reader = getReader(new File(context.get("detailsFile1Path")));
    var list2 = reader.read();
    list.addAll(list2);
    var bills = data.getBills();
    if (bills == null) {
        bills = new ArrayList();
        data.setBills(bills);
    }
    var months = getNowAnd36Month();
    // 创建6个月账单
    for each(var month in months) {
        month = getDateStr(month, "yyyy-MM-dd", "yyyy-MM");
        var bill = new BillAllData();
        bill.setBillType("");
        bill.setBillId(UUID.randomUUID().toString());
        bill.setBankName("交通银行");
        bill.setBillMonth(month);
        bill.setBillDate(yyyy_MM_dd_PARSER.parse(month + "-01"));
        bill.setCashLimit(null);
        bill.setCreditLimit(null);
        bill.setInterest(null);
        bill.setLastBalance(null);
        bill.setLastPayment(null);
        bill.setMinPayment(null);
        bill.setNewBalance(null);
        bill.setNewCharges(null);
        bill.setUsdCashLimit(null);
        bill.setUsdCreditLimit(null);
        bill.setUsdInterest(null);
        bill.setUsdLastBalance(null);
        bill.setUsdLastPayment(null);
        bill.setUsdMinPayment(null);
        bill.setUsdNewBalance(null);
        bill.setUsdNewCharges(null);
        saveExcelDebitExpenses(list, month, bill);
        if (bill.getShoppingSheets().size() > 0) {
            bills.add(bill);
        }
    }
    logger.info("获取借记卡账户明细完成");
}
//保存Excel来获取借记卡账户明细
function saveExcelDebitExpenses(list, month,  bill) {
    try {
        logger.info("交通银行taskKey:{},开始解析{}月账户明细...", context.get(LUA_TASK_KEY),month);
        var exs = bill.getShoppingSheets();
        if (exs == null) {
            exs = new ArrayList();
            bill.setShoppingSheets(exs);
        }
        var new_balance = new BigDecimal(0);
        var order_index = 0; // 排序
        var dateMap = new HashMap(); // 抓取可能有重复数据，判断去除
        var isHas = false;
        for(var i=0;i<list.size();i++){
            var tr = list.get(i);
            // 解析数据
            if (tr.size() == 11) {
                var text = tr.toString();
                if (text.contains("交易地点") && text.contains("对方开户行")) {
                    continue;
                }
                isHas = dateMap.containsKey(text);// 是否已解析过
                // 交易时间
                var sdate = tr.get(1).toString().trim();
                var d = DateUtil.parse(sdate, "yyyy-MM-dd");
                if (d == null) {
                    d = DateUtil.parse(sdate, "yyyy-MM-dd HH:mm:ss");
                }
                var pay_month = getDateStr(sdate, "yyyy-MM-dd", "yyyy-MM");
                if (!isHas && month.equals(pay_month)) {
                    dateMap.put(text, null);
                    var ex = new Expense();
                    exs.add(ex);
                    // id
                    ex.setId(UUID.randomUUID().toString());
                    // 排序
                    ex.setOrderIndex(++order_index);
                    // 卡号后四位
                    ex.setCardNum( data.getCardNum());
                    // 交易时间
                    ex.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(DateUtil.format(d, "yyyy-MM-dd HH:mm:ss")));
                    // 交易方式
                    var pay_type = tr.get(3).toString().trim();
                    ex.setTransMethod(pay_type);
                    // 摘要
                    ex.setDescription(pay_type);
                    // 消费类型
                    ex.setCategory(classify(pay_type));
                    // 币种
                    var currency_type = getCurrencyTypeStr(tr.get(6).toString().trim());
                    ex.setCurrencyType(currency_type);
                    // 支出金额
                    var pay_amount = removeIllegal(tr.get(4).toString().trim());
                    // 收入金额
                    var rev_amount = removeIllegal(tr.get(5).toString().trim());
                    if (pay_amount !== null) {
                        var am = new BigDecimal(pay_amount);
                        ex.setAmountMoney(am);
                        new_balance = new_balance.add(am);
                    } else if (rev_amount !== null) {
                        var am = new BigDecimal(rev_amount).multiply(new BigDecimal(-1));
                        ex.setAmountMoney(am);
                        new_balance = new_balance.add(am);
                    }
                    // 余额
                    var amount = removeIllegal(tr.get(10).toString().trim());
                    if (amount !== null) {
                        ex.setBalance(new BigDecimal(amount));
                    }
                    // 交易地点
                    var locale = tr.get(2).toString().trim();
                    ex.setTransAddr(locale);
                    // 对方持卡人
                    var name_on_opposite_card = tr.get(7).toString().trim();
                    ex.setNameOnOppositeCard(name_on_opposite_card);
                    // 对方账号
                    var opposite_card_no = tr.get(8).toString().trim();
                    ex.setOppositeCardNo(opposite_card_no);
                    // 对方银行
                    var opposite_bank = tr.get(9).toString().trim();
                    ex.setOppositeBank(opposite_bank);
                    // 记账日期
                    var post_date = tr.get(0).toString().trim();
                    ex.setPostDate(yyyy_MM_dd_PARSER.parse(post_date));
                }
            }
        }
        logger.info("交通银行 借记卡taskKey:{}, {}月账户明细解析完成,账单个数 {}",context.get(LUA_TASK_KEY), month, bill.getShoppingSheets().size());
    } catch (e) {
        logger.error("交通银行taskKey:{},解析{}月账户明细出错:{}", context.get(LUA_TASK_KEY),month,e);
    }
}
//抓取存款信息
function queryDebitDeposits() {
    logger.info("交通银行借记卡 taskKey:{}，开始抓取存款信息...",context.get(LUA_TASK_KEY));
    var url = "https://pbank.95559.com.cn/personbank/money/moFixConvertCurrent.do?PSessionId=" + PSessionId
        + "&x-channel=0&menuCode=P016002&random=" + Math.random() + "&ReqSafeFields=" + chbFormReqSafeFields + "&xFirstEntry=0&cardNo="
        + cardIDMap.get(card);
    var header = new LinkedHashMap();
    header.put("cookie", get_cookie());
    var content = retryUtil(url,header,"存款信息");
    storeDataToFile(context,content, cardIndex + "_deposits.html");
    context.put(cardIndex + "_deposits",content);
}

//增加重试策略
function retryUtil(url,header,description){
    var times = 1;
    var content =  RequestUtil.get(url, null, header);
    while((null==content||content.contains("交易处理中,请您稍候......"))&&times<3){
        logger.info("交通银行借记卡 taskKey:{}，第{}次重试抓取{}...",context.get(LUA_TASK_KEY),Integer.parseInt(times),description);
        Thread.sleep(5000);
        content =  RequestUtil.get(url, null, header);
        times++;
    }
    return content;
}

//解析存款信息
function analysisDebitDeposits(){
    try {
        logger.info("交通银行taskKey:{},开始解析存款数据...", context.get(LUA_TASK_KEY));
        var deposits = new ArrayList();
        data.setDeposits(deposits);
        var balance = data.getBalance();          // 活期余额
        var deposit = new CreditCardTimeDeposit();// 活期存款
        deposits.add(deposit);
        deposit.setBalance(balance);
        deposit.setCurrencyType("CNY");
        deposit.setDepositType("活期存储");
        deposit.setInterest(null);
        deposit.setPeriod(null);
        var doc = Jsoup.parse(context.get(cardIndex + "_deposits"));
        var trs = doc.select("body table > tbody > tr");
        var dateMap = new HashMap(); // 抓取可能有重复数据，判断去除
        var isHas = false;
        for each(var tr in trs) {
            var tds = tr.select("td");
            if (tds.size() == 11) {
                var sNum = tds.get(1).text();
                isHas = dateMap.containsKey(sNum);// 是否已解析过
                if (!isHas) {
                    dateMap.put(sNum, null);
                    deposit = new CreditCardTimeDeposit();
                    deposits.add(deposit);
                    // 币种
                    var currency_type = getCurrencyTypeStr(tds.get(2).text());
                    deposit.setCurrencyType(currency_type);
                    // 开户金额
                    var pay_amount = removeIllegal(tds.get(3).text());
                    // 账户余额
                    var rev_amount = removeIllegal(tds.get(4).text());
                    if (rev_amount !== null) {
                        deposit.setBalance(new BigDecimal(rev_amount));
                        balance = balance.add(new BigDecimal(rev_amount));
                    }
                    // 定期类型
                    var deposit_type = tds.get(5).text();
                    deposit.setDepositType(deposit_type.substring(0, 4));
                    // 开户日期
                    var open_date = tds.get(6).text().trim();
                    // 起息日期
                    var deposit_date = tds.get(7).text().trim();
                    deposit.setDepositDate(yyyy_MM_dd_PARSER.parse(deposit_date));
                    // 到期日期
                    var due_date = tds.get(8).text().trim();
                    deposit.setDueDate(yyyy_MM_dd_PARSER.parse(due_date));
                    var period = tds.get(9).text().trim();
                    // 存期单位
                    deposit.setPeriodUnit("MONTH");
                    // 存期
                    var ip = chrToNumber(period);
                    if ("YEAR".equals(getChrsUnit(period))) {
                        ip *= 12;
                    }
                    deposit.setPeriod(ip);
                    // 利率
                    var interest = removeIllegal(tds.get(10).text());
                    if (interest !== null) {
                        var bigdata = moneyChu100(interest);
                        deposit.setInterest(bigdata);
                    }
                }
            }
        }
        data.setBalance(balance);// 用户可用余额
    } catch (e) {
        logger.error("交通银行taskKey:{},解析存款信息出错：{}", context.get(LUA_TASK_KEY),e);
    }
}

//将金额除100
function moneyChu100( moneyStr) {
    var money = getAmount(moneyStr);
    var d = money.doubleValue() / 100;
    return getAmount(d + "");
}
//获取汉字中的数字
function  chrToNumber(s) {
    if (s == null) {
        return 0;
    }
    var val = removeIllegal(s);
    if (val !== null) {
        return Integer.valueOf(val);
    }

    s = removeNoChrNumber(s);
    var num;
    var res = new StringBuilder();
    for (var i = 0; i < s.length; i++) {
        var c = s.charAt(i);
        num = chrs.get(c);
        if (num !== null) {
            if (num == 10) {
                if (i == 0) {
                    res.append(1);
                } else if (i == s.length - 1) {
                    res.append(0);
                }
            } else {
                res.append(num);
            }
        }
    }

    return res.length == 0 ? 0 : Integer.valueOf(res.toString());
}
//获取日期单位
function getChrsUnit(s) {
    if (s == null || "".equals(s)) {
        return "";
    }

    if (s.contains("年")) {
        return "YEAR";
    } else if (s.contains("月")) {
        return "MONTH";
    } else if (s.contains("日") || s.contains("天")) {
        return "DAY";
    }

    return "";
}
//已出非汉字数字字符
function removeNoChrNumber( s) {
    for (var i = 0; i < s.length; i++) {
        var c = s.charAt(i);
        var num =  chrs.get(c);
        if (num == null) {
            s = s.replaceAll(String.valueOf(c), "");
            i--;
        }
    }
    return s;
}
//获取今天和前3+六个月的一号 yyyy-MM-dd
function getNowAnd36Month() {
    var list = new ArrayList();
    var calendar = Calendar.getInstance();
    for (var i = 0; i < 36; i++) {
        var year = calendar.get(Calendar.YEAR);
        var month = calendar.get(Calendar.MONTH) + 1;
        var day = 1;
        if (i == 0) {
            day = calendar.get(Calendar.DAY_OF_MONTH);
        }

        var m = month < 10 ? "0" + month : month+"";
        var d = day < 10 ? "0" + day : String.valueOf(day);
        list.add(year + "-" + m + "-" + d);

        calendar.add(Calendar.MONTH, -1);
    }
    return list;
}
//去掉字符串中除数字 小数点以外的其他字符
function removeIllegal(str) {
    if (str == null)
        return str;
    str = str.replaceAll("[^\\d.]+", "");
    return "".equals(str) ? null : str;
}
// 获取金额类型 人民币、 美元
function getCurrencyTypeStr( str) {
    if (str == null || str.equals("")) {
        return "";
    }
    if (str.contains("RMB") || str.contains("CNY") || str.contains("￥") || str.contains("人民币")) {
        return "CNY";
    } else {
        return "USD";
    }
}

var luaFuncs = {
    inputPwd: function (pasword) {
        var map = new HashMap();
        map.put("method", "inputPwd");
        map.put("password", pasword);
        var l = System.currentTimeMillis();
        var receice = sendAndReceive(map);
        var l1 = System.currentTimeMillis();
        logger.info("COMM 密码输入时间 {} ms", (l1 - l));
        return receice;
    },
    getCaptcha: function () {
        var map = new HashMap();
        map.put("method", "getCaptcha");
        return sendAndReceive(map);
    },
    commShow: function(){
        var map = new HashMap();
        map.put("method", "commShow");
        return sendAndReceive(map);
    },
    inputCaptcha: function (captcha) {
        var map = new HashMap();
        map.put("method", "inputCaptcha");
        map.put("captcha", captcha);
        return sendAndReceive(map);
    },
    inputMobileCode: function (verifyMessage) {
        var map = new HashMap();
        map.put("method", "inputMobileCode");
        map.put("mobileCode", verifyMessage);
        return sendAndReceive(map);
    },
    setConfirm: function () {
        var map = new HashMap();
        map.put("method", "setConfirm");
        return sendAndReceive(map);
    },
    /**
     * 判断首页是否渲染完成
     *
     * @return
     */
    checkIsOk: function () {
        var map = new HashMap();
        map.put("method", "checkIsOk");
        return sendAndReceive(map);
    },
    /**
     *
     * @param name
     * @returns {*}
     */
    saveHtmlAndImageFunc: function (name) {
        var map = new LinkedHashMap();
        map.put("name", name);
        map.put("method", "saveHtmlAndImageFunc");
        return sendAndReceive(map);
    },
}

